package com.xiaolin.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @ClassName TestDynamicProxyByCglib
 * @Description TODO
 * @Detail 使用cglib实现动态代理
 *              步骤：
 *                  1、导入cglib的包，它包含在spring-core包中
 *                  2、创建一个目标类
 *                  3、创建一个cglib工厂类，实现 MethodInterceptor 接口，重写 intercept 方法
 *                  4、在cglib工厂类编写一个获取代理对象方法
 *               总结：
 *                  与JDK动态代理不同，cglib动态代理不需要目标类去实现一个接口
 * @Author MyPC
 * @Date 2020/9/27
 * @Version 1.0
 */
public class TestDynamicProxyByCglib {
    public static void main(String[] args) {
        Publish publish=new Publish();
        CglibFactory cglibFactory= new CglibFactory(publish);
        Publish proxy = (Publish) cglibFactory.getProxy();
        proxy.publish();
    }
}

/**
 * 目标对象
 */
class Publish{
    public void publish(){
        System.out.println("出版书籍");
    }
}

/**
 * 代理工厂
 */
class CglibFactory implements MethodInterceptor{

    private Object target;

    public CglibFactory(Object target){
        this.target=target;
    }

    /**
     * 创建代理对象
     * @return
     */
    public Object getProxy() {
        Enhancer enhancer=new Enhancer();
        //设置代理对象的父类
        enhancer.setSuperclass(target.getClass());
        //设置回调函数
        enhancer.setCallback(this);
        //创建子类代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("整理稿子，准备出版");
        Object invoke = method.invoke(target, args);
        System.out.println("宣传");
        return null;
    }
}
